/**
* file name  : GetCSV.java
* authors    : Luciano Xumerle
* created    : ven 12 ago 2005 15:49:47 CEST
*
* Copyright (c) 2004-2005 Luciano Xumerle. All rights reserved.
*
* This file is part of gephinfo.
*
* gephinfo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*/

package it.ciano.jenoware;

import it.ciano.util.CFile;
import it.ciano.util.CString;

/**
 * The class GetFile provides an interface to export data contained Pedigree
 * into a Pedigree object to file.
 *
 * @author Luciano Xumerle
 * @version 0.0.1
 */
public class GetCSV extends GetFile {

    final private String EXT=".csv";

    //
    // private vars used to store the field names
    //
    private String pheno[];
    private String geno[];

    private String _null;

    private String sep;
    private boolean pedInfo;
    private boolean headerInfo;

    /**
     * Class Constructor.
     *
     * @param pedigree a populated Pedigree object.
     * @param separator the separator used by CSV file.
     * @param printPedInfo if true then print the pedigree info (fam, sbj, fth, mth, ...).
     */
    public GetCSV ( Pedigree pedigree, String separator, boolean printHeader, boolean printPedInfo ) {
        super ( pedigree );
        pheno = getPed().getPhenotypesList();
        geno = getPed().getMarkersList();
        sep = separator;
        _null="";
        pedInfo = printPedInfo;
        headerInfo=printHeader;
    }

    /**
     * Sets the null value to be used with empty fields.
     *
     * @param val
     */
    public void setNullValue ( String val ) {
        _null=val;
    }

    /**
     * Overriding toString method
     *
     * @return all informations that will be contained into the destination files.
     */
    public String toString() {
        StringBuffer res = new StringBuffer();
        if ( headerInfo ) {
            res.append ( getCSVheader() );
            res.append ( "\n" );
        }
        // PRINT EVERY SUBJECT
        Sbj id[] = getPed().getListSbj();
        for ( int j = 0; j < id.length; j++ ) {
            String[] fams=id[ j ].getFML();
            if ( fams == null  ) {
                res.append ( getCSVsubject ( "", id[ j ] ) );
                res.append ( "\n" );
            } else {
                for ( int ff=0; ff<fams.length; ff++ ) {
                    res.append ( getCSVsubject ( fams[ff], id[ j ] ) );
                    res.append ( "\n" );
                }
            }
        }
        return res.toString();
    }

    /**
     * Returns the CSV in PedPhase input file.
     *
     * @return the CSV in PedPhase input file.
     */
    public String toPedPhase() {
        StringBuffer res = new StringBuffer();
        String _sep="\t";

        // PRINT EVERY SUBJECT
        // format file is: fml sbj fth mth sex 0 0 markers
        Sbj id[] = getPed().getListSbj();
        for ( int j = 0; j < id.length; j++ ) {
            String[] fams=id[ j ].getFML();
            for ( int ff=0; ff<fams.length; ff++ ) {
                res.append ( fams[ff] );
                res.append ( _sep );
                res.append ( id[ j ].getSBJ ( fams[ff] ) );
                res.append ( _sep );
                res.append ( id[ j ].getFTH ( fams[ff] ) );
                res.append ( _sep );
                res.append ( id[ j ].getMTH ( fams[ff] ) );
                res.append ( _sep );
                res.append ( id[ j ].getSEX() );
                res.append ( _sep );
                res.append ( "0" );
                res.append ( _sep );
                res.append ( "0" );
                if ( geno != null )
                    for ( int i = 0; i < geno.length; i++ ) {
                        res.append ( _sep );
                        res.append ( id[j].getGenotype ( geno[ i ] ).getStringCSV ( _sep, "0", null ) );
                    }
                res.append ( "\n" );
            }
        }
        return res.toString();
    }

    /**
     * Creates a CSV file with the given name.
     *
     * @return true if all operations are ok.
     */
    public boolean createsFile ( String filename ) {
        setFilename ( filename );
        return CFile.saveString ( getFilename() + EXT, toString() );
    }

    /**
     * Creates a CSV file named "out.csv".
     *
     * @return true if all operations are ok.
     */
    public boolean createsFile() {
        return CFile.saveString ( getFilename() + EXT, toString() );
    }

    /**
     * Returns the String with the header of a CSV file.
     * The method uses the CsvHead.fixedFields list to
     * set the header.
     *
     * @return the header String.
     */
    public String getCSVheader() {
        // PRINT CSV HEADER
        StringBuffer out = new StringBuffer();
        String[] field=CsvHead.fixedFields;
        if ( pedInfo ) {
            out.append ( '!' );
            out.append ( CString.join ( field, sep  ) );
            out.append ( sep );
        } else {
            out.append ( "id" );
            out.append ( sep );
            out.append ( field[4]  ); // sex field
            out.append ( sep );
        }
        if ( pheno != null )
            for ( int i = 0; i < pheno.length; i++ ) {
                out.append ( pheno[ i ] );
                out.append ( sep );
            }
        if ( geno != null )
            for ( int i = 0; i < geno.length; i++ ) {
                out.append ( Genotype.getHeaderCSV ( geno[ i ], sep, "" ) );
                out.append ( sep );
            }
        return out.toString().substring ( 0, ( out.length() - sep.length() ) );
    }

    /**
     * Returns the String with the fields of a CSV file of a subject.
     *
     * @param id the Sbj String id.
     * @return the subject String.
     */
    public String getCSVsubject ( String fml, Sbj id ) {
        // get Sbj fiels
        StringBuffer out = new StringBuffer();
        if ( !pedInfo ) {
            out.append ( id.getID() );
            out.append ( sep );
            out.append ( id.getSEX() );
            out.append ( sep );
        } else {
            out.append ( fml );
            out.append ( sep );
            out.append ( id.getSBJ ( fml ) );
            out.append ( sep );
            out.append ( id.getFTH ( fml ) );
            out.append ( sep );
            out.append ( id.getMTH ( fml ) );
            out.append ( sep );
            out.append ( id.getSEX() );
            out.append ( sep );
            out.append ( id.getProband ( fml ) );
            out.append ( sep );
            out.append ( id.getID() );
            out.append ( sep );
        }

        if ( pheno != null )
            for ( int i = 0; i < pheno.length; i++ ) {
                out.append ( id.getPhenotype ( pheno[ i ] ).getValue() );
                out.append ( sep );
            }
        if ( geno != null )
            for ( int i = 0; i < geno.length; i++ ) {
                out.append ( id.getGenotype ( geno[ i ] ).getStringCSV ( sep, _null, null ) );
                out.append ( sep );
            }
        return out.toString().substring ( 0, ( out.length() - sep.length() ) );
    }

} // end class

